import { useRef, useCallback } from 'react';

// 用于给一个异步函数增加竞态锁，防止并发执行。
// 如在 submit 函数执行完成前，其余的点击动作都会被忽略。
function useLockFn<P extends any[] = any[], V extends any = any>(
  fn: (...agrs: P) => Promise<V>
) {
  const lockRef = useRef(false);

  return useCallback(
    async (...args: P) => {
      if (lockRef.current) return;
      lockRef.current = true;

      try {
        const ret = await fn(...args);
        lockRef.current = false;
        return ret;
      } catch (error) {
        lockRef.current = false;
        throw error;
      }
    },
    [fn]
  );
}

export default useLockFn;
